﻿--[[
    @Brief    Token verify
    @Author    jameszhai
    @Date    2015-05-26
--]]

--[[
// 取消密保验证
MSG_BEGIN(Msg_CancelPGVfy)
    JSONB(int, service_id);
    JSONB(int, uin);
MSG_END
--]]

ETokenType = 
{
    ttPGPhone = 2;        -- 密保手机
    ttPhoneTK = 4;        -- 手机令牌
    ttQQToken = 6;        -- QQ令牌
};

EEditRes = 
{
    sNrlBG = "3HIMAGES:bottom_bar\\box.png?7,144,15,168;bottom_bar\\box.png?19,144,27,168;bottom_bar\\box.png?31,144,39,168;Stretch;0;";
    sClkBG = "3HIMAGES:bottom_bar\\box.png?55,144,63,168;bottom_bar\\box.png?67,144,75,168;bottom_bar\\box.png?79,144,87,168;Stretch;null;";
    sErrBG = "3HIMAGES:bottom_bar\\box.png?103,144,111,168;bottom_bar\\box.png?115,144,123,168;bottom_bar\\box.png?127,144,135,168;Stretch;null;";

};

TEditUIHelper = 
{
    AddEdit = function(nEditID)
        ui_utility.setproperty_by_id(nEditID, "OnSetFocus", "TEditUIHelper.OnEditEnter");
        ui_utility.setproperty_by_id(nEditID, "OnKillFocus", "TEditUIHelper.OnEditLeave");
    end;

    DelEdit = function(nEditID)
        ui_utility.setproperty_by_id(nEditID, "OnSetFocus", "");
        ui_utility.setproperty_by_id(nEditID, "OnKillFocus", "");
    end;

    OnEditEnter = function(pUILib, nEditID, wParam)
        -- ui_utility.setproperty_by_id(nEditID, "Background", EEditRes.sClkBG);
        ui_utility.setproperty_by_id(nEditID, "BorderColor", "0x2D2D2D");
    end;

    OnEditLeave = function(pUILib, nEditID, wParam)
        -- ui_utility.setproperty_by_id(nEditID, "Background", EEditRes.sNrlBG);
        ui_utility.setproperty_by_id(nEditID, "BorderColor", "0x9E9E9E");
    end;

};

TokenVfy = 
{
    InitCtrl = function()   
        TokenVfy.zPGTypes = 
        {
            [2] = LoadStr("STR_LOGIN_PWDGUARD_PHONE");        -- "密保手机";
            [4] = LoadStr("STR_LOGIN_MOBILE_TOKEN");    -- "手机令牌";
            [6] = LoadStr("STR_LOGIN_QQ_TOKEN");        -- "QQ令牌";
        };

        local pTPFUI = base_utility.get_component_adapter("ITpf_ui", "ierd_tgp.tpf_ui.GetTPFUI();");

        if nil ~= pTPFUI then
            pTPFUI:AddLuaListener(ierd_tgp.login_mgr.LOGIN_ON_PASSGUARD_CHECK, "TokenVfy.OnChkPwdGaurd");
            pTPFUI:AddLuaListener(ierd_tgp.login_mgr.LOGIN_ON_PASSGUARD_CHECK_FAILED, "TokenVfy.OnChkFail");
            pTPFUI:AddLuaListener(ierd_tgp.login_mgr.LOGIN_ON_REQUEST_GAME_ST_COMPLETE, "TokenVfy.OnReqSTOK");
            pTPFUI:AddLuaListener(ierd_tgp.login_mgr.LOGIN_ON_REQUEST_GAME_ST_FAILED, "TokenVfy.OnReqSTFail");
        else
            TGPLog.LogE("TokenVfy", "UnInitCtrl, get tpf ui fail.");
        end;

        -- comm_center.reg_service("Svr_ShowTokenVfy", "TokenVfy.OnShowVfy");
    end;

    OnShowVfy = function()
        if TokenVfy.CreateView() then
            TokenVfy.bIsError = false;
            TokenVfy.UpdateView();
            TokenVfy.pDlgView:Show(TRUE);
        end;
    end;

    UnInitCtrl = function()
        TokenVfy.DestroyView();

        local pTPFUI = base_utility.get_component_adapter("ITpf_ui", "ierd_tgp.tpf_ui.GetTPFUI();");

        if nil ~= pTPFUI then
            pTPFUI:RemoveLuaListener(ierd_tgp.login_mgr.LOGIN_ON_PASSGUARD_CHECK, "TokenVfy.OnChkPwdGaurd");
            pTPFUI:RemoveLuaListener(ierd_tgp.login_mgr.LOGIN_ON_PASSGUARD_CHECK_FAILED, "TokenVfy.OnChkFail");
            pTPFUI:RemoveLuaListener(ierd_tgp.login_mgr.LOGIN_ON_REQUEST_GAME_ST_COMPLETE, "TokenVfy.OnReqSTOK");
            pTPFUI:RemoveLuaListener(ierd_tgp.login_mgr.LOGIN_ON_REQUEST_GAME_ST_FAILED, "TokenVfy.OnReqSTFail");
        else
            TGPLog.LogE("TokenVfy", "UnInitCtrl, get tpf ui fail.");
        end;
    end;

    -- Pasword guard check
    OnChkPwdGaurd = function(nEvtID, sJson)
        TokenVfy.pPGInfo = base_utility.json_to_table(sJson);

        if nil == TokenVfy.pPGInfo then
            TGPLog.LogE("TokenVfy", "Check password guard, J->T fail.");
            return;
        end;

        if TokenVfy.CreateView() then
            TokenVfy.bIsError = false;
            TokenVfy.nCurUin  = TokenVfy.pPGInfo.uin;
            TokenVfy.nSvrID   = TokenVfy.pPGInfo.service_id;
            TokenVfy.nPGTime  = os.time();

            TokenVfy.UpdateView();
            TokenVfy.pDlgView:Show(TRUE);
        else
            TGPLog.LogE("TokenVfy", "On check password guard, create view fail.");
        end;
    end;

    -- 验证失败
    OnChkFail = function(nEvtID, sJson)
        TokenVfy.bIsError = true;
        TokenVfy.UpdateView();            -- 显示失败
    end;

    -- 请求成功
    OnReqSTOK = function(nEvtID, sJson)
        TGPLog.LogI("TokenVfy", "on request gamest complete:" .. sJson);

        local zInfo = base_utility.json_to_table(sJson);

        if zInfo.service_id == TokenVfy.nSvrID then
            TokenVfy.DestroyView();
        end;
    end;

    OnReqSTFail = function(nEvtID, sJson)
        TGPLog.LogI("TokenVfy", "on request gamest fail:" .. sJson);
    end;

    -- 创建界面
    CreateView = function()
        if nil ~= TokenVfy.pDlgView then
            return true;
        end;

        local     nViewID = layout_mgr.restore_layout("login\\TokenVfy.xml");

        if nil == nViewID or 0 == nViewID then
            TGPLog.LogE("TokenVfy", "Load layout fail.");
            return false;
        end;
        
        TokenVfy.pDlgView = ui_utility.get_ctrl_ptr_by_id(nViewID);

        if nil == TokenVfy.pDlgView then
            TGPLog.LogE("TokenVfy", "Get dialog fail.");
            return false;
        end;

        if (TokenVfy.CheckTokenUI(nViewID) and TokenVfy.CheckErrorUI(nViewID)) then
            local nTempID = ui_utility.get_ctrl_id_by_path(nViewID, "TitleBarCtn\\Btn_close");

            if nil == nTempID or 0 == nTempID then
                TGPLog.LogE("TokenVfy", "Get close button fail.");
                return false;
            end;
            ui_utility.setproperty_by_id(nTempID, "OnClick", "TokenVfy.OnClkClose");

            return true;
        else
            return false;
        end;
    end;

    -- 检查Token界面
    CheckTokenUI = function(nViewID)
        TokenVfy.pTokenUI = ui_utility.get_ctrl_ptr_by_path(nViewID, "pnlToken");

        if nil == TokenVfy.pTokenUI then
            TGPLog.LogE("TokenVfy", "Get token UI fail.");
            return false;
        end;

        nViewID = TokenVfy.pTokenUI:GetControlID();

        TokenVfy.pCbbType = ui_utility.get_ctrl_ptr_by_path(nViewID, "cbbType");
        if nil == TokenVfy.pCbbType then
            TGPLog.LogE("TokenVfy", "Get type combobox fail.");
            return false;
        end;
        ui_utility.setproperty_by_id(TokenVfy.pCbbType:GetControlID(), "OnCBSelectItem", 
                                     "TokenVfy.OnSelItem");
        TEditUIHelper.AddEdit(TokenVfy.pCbbType:GetControlID());

        TokenVfy.pEdtCode = ui_utility.get_ctrl_ptr_by_path(nViewID, "edtToken");
        if nil == TokenVfy.pEdtCode then
            TGPLog.LogE("TokenVfy", "Get token input edit fail.");
            return false;
        end;
        TEditUIHelper.AddEdit(TokenVfy.pEdtCode:GetControlID());

        TokenVfy.pTokenTip = ui_utility.get_ctrl_ptr_by_path(nViewID, "lblToken");
        if nil == TokenVfy.pTokenTip then
            TGPLog.LogE("TokenVfy", "Get token tips fail.");
            return false;
        end;

        local     nTempID = ui_utility.get_ctrl_id_by_path(nViewID, "btnConfig");

        if nil == nTempID or 0 == nTempID then
            TGPLog.LogE("TokenVfy", "Get config button fail.");
            return false;
        end;
        ui_utility.setproperty_by_id(nTempID, "OnClick", "TokenVfy.OnClkConfig");

        nTempID = ui_utility.get_ctrl_id_by_path(nViewID, "btnConfirm");
        if nil == nTempID or 0 == nTempID then
            TGPLog.LogE("TokenVfy", "Get confirm button fail.");
            return false;
        end;
        ui_utility.setproperty_by_id(nTempID, "OnClick", "TokenVfy.OnClkConfirm");

        nTempID = ui_utility.get_ctrl_id_by_path(nViewID, "btnCancel");
        if nil == nTempID or 0 == nTempID then
            TGPLog.LogE("TokenVfy", "Get cancel button fail.");
            return false;
        end;
        ui_utility.setproperty_by_id(nTempID, "OnClick", "TokenVfy.OnClkCancel");

        return true;
    end;

    -- 检查错误界面
    CheckErrorUI = function(nViewID)
        TokenVfy.pErrorUI = ui_utility.get_ctrl_ptr_by_path(nViewID, "pnlError");

        if nil == TokenVfy.pErrorUI then
            TGPLog.LogE("TokenVfy", "Get error panel fail.");
            return false;
        end;

        nViewID = TokenVfy.pErrorUI:GetControlID();

        TokenVfy.pErrTips = ui_utility.get_ctrl_ptr_by_path(nViewID, "rtbTips");
        if nil == TokenVfy.pErrTips then
            TGPLog.LogE("TokenVfy", "Get error tips control fail.");
            return false;
        end;

        local     nTempID = ui_utility.get_ctrl_id_by_path(nViewID, "btnRetry");
        if nil == nTempID or 0 == nTempID then
            TGPLog.LogE("TokenVfy", "Get retry button fail.");
            return false;
        end;
        ui_utility.setproperty_by_id(nTempID, "OnClick", "TokenVfy.OnClkRetry");

        nTempID = ui_utility.get_ctrl_id_by_path(nViewID, "btnCancel");
        if nil == nTempID or 0 == nTempID then
            TGPLog.LogE("TokenVfy", "Get cancel button fail.");
            return false;
        end;
        ui_utility.setproperty_by_id(nTempID, "OnClick", "TokenVfy.OnClkCancel");

        nTempID = ui_utility.get_ctrl_id_by_path(nViewID, "btnDetail");
        if nil == nTempID or 0 == nTempID then
            TGPLog.LogE("TokenVfy", "Get detail button fail.");
            return false;
        end;
        ui_utility.setproperty_by_id(nTempID, "OnClick", "TokenVfy.OnClkDetail");

        return true;
    end;

    -- 销毁界面
    DestroyView = function()
        TokenVfy.StopTmr();

        if nil ~= TokenVfy.pDlgView then
            TokenVfy.pDlgView:Show(FALSE);
            layout_mgr.remove_ctrl(TokenVfy.pDlgView:GetControlID());

            TokenVfy.pDlgView = nil;

            if nil ~= TokenVfy.pEdtCode then
                TEditUIHelper.DelEdit(TokenVfy.pEdtCode:GetControlID());
            end;

            if nil ~= TokenVfy.pCbbType then
                TEditUIHelper.DelEdit(TokenVfy.pCbbType:GetControlID());
            end;

            -- 验证界面
            TokenVfy.pTokenUI = nil;
            TokenVfy.pCbbType = nil;
            TokenVfy.pEdtCode = nil;
            TokenVfy.pTokenTip= nil;
            
            -- 错误界面
            TokenVfy.pErrorUI = nil;
            TokenVfy.pErrTips = nil;            
        end;
    end;

    -- 更新界面
    UpdateView = function()
        if TokenVfy.bIsError then
            if nil ~= TokenVfy.pTokenUI then
                TokenVfy.pTokenUI:Show(FALSE);
            end;

            if nil ~= TokenVfy.pErrorUI then
                TokenVfy.pErrorUI:Show(TRUE);
            end;

            if nil ~= TokenVfy.pErrTips then
                if  ETokenType.ttPhoneTK == TokenVfy.nCurType then
                    TokenVfy.StartTmr();
                    TokenVfy.ShowTime();
                else
                    TokenVfy.StopTmr();

                    -- local     sTemp = "您输入的动态密码有误，请仔细核对。";
                    local     sText = U8toCUIStr(LoadStr("STR_LOGIN_ERRPIN_TIPS"));    -- sTemp);
                    TokenVfy.pErrTips:Clear();
                    TokenVfy.pErrTips:PushBackHtmlString(sText);
                end;
            else
                TGPLog.LogE("TokenVfy", "Error control is null.");
            end;
        else
            TokenVfy.StopTmr();

            if nil == TokenVfy.pCbbType then
                TGPLog.LogI("TokenVfy", "Update token view, type control is null.");
                return;
            end;

            if nil ~= TokenVfy.pTokenUI then
                TokenVfy.pTokenUI:Show(TRUE);
            end;

            if nil ~= TokenVfy.pErrorUI then
                TokenVfy.pErrorUI:Show(FALSE);
            end;

            TokenVfy.pCbbType:DeleteAll();

            if nil ~= TokenVfy.pPGInfo then
                local     nSelIdx = -1;

                for nIdx = 1, TokenVfy.pPGInfo.count do
                    local     nType = TokenVfy.pPGInfo.types[nIdx];
                    local     sType = TokenVfy.zPGTypes[nType];

                    if nil ~= sType then
                        local sText = U8toCUIStr(sType);
                        TokenVfy.pCbbType:AppendItem(sText);
                    end;

                    if TokenVfy.nLstType == nType then
                        nSelIdx = nIdx - 1;
                        TokenVfy.pCbbType:SetCurSel(nSelIdx);
                    end;
                end;

                if -1 == nSelIdx then
                    if (nil == TokenVfy.nLstType) or (0 == TokenVfy.nLstType) then
                        TokenVfy.nLstType = TokenVfy.pPGInfo.types[1];
                    end;

                    TokenVfy.ChangeType(TokenVfy.nLstType);
                end;
            end;
        end;
    end;

    ChangeType = function(nType)
        if (TokenVfy.nCurType == nType) then
            TGPLog.LogI("TokenVfy", "Trying to change to same type:"..tostring(nType));
            return;
        end;

        if nil == TokenVfy.pTokenTip then
            TGPLog.LogI("TokenVfy", "Token tips control is  null.");
            return;
        end;

        if (nil == TokenVfy.pPGInfo ) or (nil == TokenVfy.pCbbType) or 
           (nil == TokenVfy.pEdtCode) then
            TGPLog.LogI("TokenVfy", "Token PG information is  null.");
            return;
        end;

        TokenVfy.nCurType = nType;

        local     sDesp = LoadStr("STR_LOGIN_INPUTVFYCODE_TIPS");    -- "请输入验证码";

        if ETokenType.ttQQToken == nType then        -- QQ令牌
            sDesp = LoadStr("STR_LOGIN_QQTOKEN_TIPS");    -- "请输入QQ令牌上的6位数字动态密码";
        elseif ETokenType.ttPGPhone == nType then    -- 手机密保
            sDesp = LoadStr("STR_LOGIN_EDITSMS_TIPS") .. TokenVfy.pPGInfo.mobile_msg ..
                    LoadStr("STR_LOGIN_SENDTO") .. TokenVfy.pPGInfo.sys_number ..
                    LoadStr("STR_LOGIN_GETVFYCODE");    -- "请编辑短信" .. TokenVfy.pPGInfo.mobile_msg .. "发送到" .. TokenVfy.pPGInfo.sys_number .. "获取验证码";
        elseif ETokenType.ttPhoneTK == nType then    -- 手机令牌
            sDesp = LoadStr("STR_LOGIN_MTOKEN_TIPS");    -- "请用QQ安全中心获取6位数字动态密码";
        end;

        local     sText = U8toCUIStr(sDesp);
        TokenVfy.pTokenTip:SetText(sText);

        local     sType = TokenVfy.zPGTypes[nType];

        if ETokenType.ttPGPhone == nType then
            sType = sType .. TokenVfy.pPGInfo.mobile;
        end;

        local     sTemp = U8toCUIStr(sType);
        TokenVfy.pCbbType:SetSelString(sTemp);
        TokenVfy.pEdtCode:SetFocus();
    end;

    OnClkConfig = function(pUILib, nBtnID)
        local url = LoadStr("SAFE_SERVICE_URL");
        web_utility.open_browser(url, false, true);
        TGPLog.LogI("TokenVfy", "Click config.");
    end;

    OnClkConfirm= function(pUILib, nBtnID)
        TGPLog.LogI("TokenVfy", "Submit password guard check.");

        local     pLoginMgr = base_utility.get_component_adapter("ILogin_mgr",
                            "ierd_tgp.login_mgr.GetLoginMgr();");

        if nil == pLoginMgr then
            TGPLog.LogE("TokenVfy", "Confirm, Get login manager fail.");
            return;
        end;

        if nil == TokenVfy.pEdtCode then
            TGPLog.LogE("TokenVfy", "Confirm, edit code is null.");
            return;
        end;

        local     sText = TokenVfy.pEdtCode:GetText();

        if (nil == sText) or ("" == sText) then
            TokenVfy.pEdtCode:SetFocus();
            return;
        end;

        local     sCode = CUIStrtoU8(sText);
        local     zParam = ierd_tgp.login_mgr.PassguardAnswerInfoPod:new();

        zParam.service_id = TokenVfy.nSvrID;
        zParam.uin           = TokenVfy.nCurUin;
        zParam.type       = TokenVfy.nCurType;
        zParam.answer       = sCode;
        pLoginMgr:VerifyByPassguard(zParam);
        zParam:delete();

        TokenVfy.nLstType = TokenVfy.nCurType;
    end;

    -- 取消
    OnClkCancel = function(pUILib, nBtnID)
        local     pLoginMgr = base_utility.get_component_adapter("ILogin_mgr",
                            "ierd_tgp.login_mgr.GetLoginMgr();");

        if nil == pLoginMgr then
            TGPLog.LogE("TokenVfy", "Cancel Get login manager fail.");
            return;
        end;

        pLoginMgr:CancelPassguardCheck(TokenVfy.nSvrID, TokenVfy.nCurUin, 0);        

        if nil ~= TokenVfy.pDlgView then
            TokenVfy.pDlgView:Show(FALSE);
            TokenVfy.DestroyView();
        else
            TGPLog.LogE("TokenVfy", "Click close, dialog is null.");
        end;

        local     zParam = {};

        zParam["service_id"] = TokenVfy.nSvrID;
        zParam["uin"       ] = TokenVfy.nCurUin;
        comm_center.send_broadcast("Msg_CancelPGVfy", zParam);

        -- 失败了，把主界面拉起来
        event_center.send_event(mainframe_event.SHOW_MAIN_WND, "");
    end;

    -- 详细信息
    OnClkDetail = function(pUILib, nBtnID)
        local sUrl = LoadStr("KF_URL") .. "#hid=1401";  -- 手机验证

        if ETokenType.ttPhoneTK == TokenVfy.nCurType then
            url = LoadStr("KF_URL") .. "#hid=1403";      -- 手机令牌
        elseif ETokenType.ttQQToken == TokenVfy.nCurType then
            url = LoadStr("KF_URL") .. "#hid=1399";      -- qq令牌
        end;

        web_utility.open_browser(url, false, true);    
    end;

    -- 重试
    OnClkRetry = function(pUILib, nBtnID)
        TokenVfy.bIsError = false;
        TokenVfy.UpdateView();
    end;

    -- 点击关闭按钮
    OnClkClose = function(pUILib, nBtnID)
        TokenVfy.OnClkCancel(pUILib, nBtnID);
    end;

    OnSelItem = function()
        if nil == TokenVfy.pCbbType then
            TGPLog.LogE("TokenVfy", "On select item, token type combobox is null.");
            return;
        end;

        local sText, pMem = NewUIStr(100);

        TokenVfy.pCbbType:GetEditString(sText, 100);

        local sTemp = UIStrtoU8(sText);

        for nIdx = 1, TokenVfy.pPGInfo.count, 1 do
            local     nType = TokenVfy.pPGInfo.types[nIdx];
            local     sType = TokenVfy.zPGTypes[nType];

            if (nil ~= sType) and (sTemp == sType) then
                TokenVfy.ChangeType(nType);
                break;
            end;
        end;
    end;

    StartTmr = function()
        if TokenVfy.bTmrStart then
            return;
        end;

        local pTPFUI = base_utility.get_component_adapter("ITpf_ui",
                            "ierd_tgp.tpf_ui.GetTPFUI();");

        if nil ~= pTPFUI then
            pTPFUI:AddInterval("TokenVfy.OnTimer", 1000, 0);
        else
            TGPLog.LogE("TokenVfy", "Add interval fail.");
        end;

        TokenVfy.bTmrStart = true;
    end;

    StopTmr = function()
        if TokenVfy.bTmrStart then
            local pTPFUI = base_utility.get_component_adapter("ITpf_ui",
                                "ierd_tgp.tpf_ui.GetTPFUI();");

            if nil ~= pTPFUI then
                pTPFUI:RemoveInterval("TokenVfy.OnTimer", 0);
            else
                TGPLog.LogE("TokenVfy", "Add interval fail.");
            end;

            TokenVfy.bTmrStart = false;
        end;
    end;

    OnTimer = function()
        TokenVfy.ShowTime();
    end;

    ShowTime = function()
        if nil ~= TokenVfy.pErrTips then
            local tNow  = os.time();
            local tTime = tNow;

            if nil ~= TokenVfy.pPGInfo then
                 tTime = tTime - TokenVfy.nPGTime + TokenVfy.pPGInfo.server_time;
            end;

            local sTemp = os.date(LoadStr("STR_LOGIN_TIME_FMT"), tTime);        -- "%Y年%m月%d日  %X"

            TGPLog.LogI("TokenVfy", "Set server time:" .. sTemp);

            sTemp = LoadStr("STR_LOGIN_TOKENERR_TIPS") .. sTemp;
            --[[
            sTemp = "您输入的动态密码有误，请仔细核对。<b><b>" ..
                     "<f c=\"0x75777c\">多次验证都无法通过？推荐您校准手机令牌时间</f><b><b>" ..
                     "服务器时间：" .. sTemp;
            ]]
            ui_utility.setproperty_by_id(TokenVfy.pErrTips:GetControlID(), "Caption", sTemp);
        end;
    end;

    -- UI controls
    pDlgView = nil;

    -- 验证界面
    pTokenUI = nil;
    pCbbType = nil;
    pEdtCode = nil;
    pTokenTip= nil;
    
    -- 错误界面
    pErrorUI = nil;
    pErrTips = nil;

    bIsError = false;
    bTmrStart= false;

    -- 状态
    nSvrID   = 0;
    nCurUin  = 0;
    nPGTime  = 0;        -- 收到验证请求时间
    pPGInfo  = nil;        -- 密保信息

    -- 验证方式
    zPGTypes = nil;
    nLstType = nil;
    nCurType = nil;

};